using System;
using System.Text;
using Opticon.Bcrctl;

namespace CoreMobile.bce
{
    public interface IBCENotifiable
    {
        void receiverDataFromReader(object sender, BarcodeDecoder.ScanEventArgs e);
        // TODO: rename to receiveDataFromReader
    }

    public class BCEReader
    {
        private BarcodeReader barcodeReader = new BarcodeReader();
        private BarcodeDecoder barcodeDecoder = new BarcodeDecoder();

        private byte[] barcodeBuffer = new byte[4096];


        private IBCENotifiable _bceNotifiable;

        public BarcodeDecoder BarcodeDecoder
        {
            get { return barcodeDecoder; }
        }

        public static BCEReader getReaderWith(IBCENotifiable n)
        {
            //uniqueReader.Destroy();
            uniqueReader = new BCEReader(n);
            return uniqueReader;
        }

        private static BCEReader uniqueReader = null;
        private BCEReader(IBCENotifiable bceNotifiable)
        {
            _bceNotifiable = bceNotifiable;
            init();
        }

        public void init()
        {/*
            int size = Marshal.SizeOf(typeof(BarcodeReader.BCR_SETTINGS));
            IntPtr buffer = Marshal.AllocHGlobal(size);
            try
            {
                Marshal.Copy(barcodeReader.BCRSettings, 0, buffer, size);
                bcrSettings = (BarcodeReader.BCR_SETTINGS)Marshal.PtrToStructure(buffer, typeof(BarcodeReader.BCR_SETTINGS));
            }
            catch
            {
                MessageBox.Show("Fail to get all settings.");
                //this.Close();
                return;
            }
            finally
            {
                Marshal.FreeHGlobal(buffer);
            }
            bool bRet = true;
            bRet = barcodeDecoder.GetCommandConfigFilePath(commandFilePath, 100);
            if (!bRet)
            {
                MessageBox.Show("Fail to get command config file path.");
                //this.Close();
                return;
            }
            String strPath = "";
            strPath = commandFilePath.ToString() + ".tmp";
            try
            {
                File.Copy(commandFilePath.ToString(), strPath, true);
            }
            catch
            {
                MessageBox.Show("Fail to save command config file.");
                this.Close();
                return;
            }

            // Get the power status.Turn on the Power if the power is off. 
            if (!barcodeReader.PowerOn)
            {
                barcodeReader.PowerOn = true;
            }

            // Set to default.
            bRet = barcodeReader.SetDefault();
            if (!bRet)
            {
                MessageBox.Show("Fail to set default.");
                doExit();
                this.Close();
                return;
            }*/

            // Set output mode to "Data buffer" mode.
            barcodeReader.OutputMode = BarcodeReader.DataOutput.BUFFER;

            // Enable trigger key.
            if (!barcodeReader.TriggerKeyEnabled)
                barcodeReader.TriggerKeyEnabled = true;
            barcodeReader.TriggerKeySetting = BarcodeReader.TriggerKey.SIDE | BarcodeReader.TriggerKey.F2;
            /*
            RegistryKey regKey = Registry.LocalMachine;
            if (regKey.OpenSubKey("Software\\Microsoft\\Shell\\Keys\\40C3") != null)
            {
                barcodeReader.TriggerKeySetting |= BarcodeReader.TriggerKey.F3 | BarcodeReader.TriggerKey.F4;
            }

            // Clear buffer.
            bRet = barcodeDecoder.ClearBuffer();
            if (!bRet)
            {
                MessageBox.Show("Fail to clear buffer.");
                doExit();
                this.Close();
                return;
            }*/

            BarcodeDecoder.DataHandler
                += _bceNotifiable.receiverDataFromReader;
        }

        public string preProcess(BarcodeDecoder.ScanEventArgs e)
        {
            if (e.DataLength == 0)  return null;
            
            int nTempLength = 0;
            uint dwSuffix = 0;
            dwSuffix = BarcodeDecoder.SuffixChar;
            if (dwSuffix != 0)
            {
                nTempLength = (int)e.DataLength - 1;
            }
            else
            {
                nTempLength = (int)e.DataLength;
            }
            if (e.ReadStatus == BarcodeDecoder.LastReadStatusList.GOOD)
            {
                UnicodeEncoding enc = new UnicodeEncoding();
                Encoding ascii = Encoding.Default;
                Encoding unicode = Encoding.Unicode;
                barcodeBuffer = Encoding.Convert(ascii, unicode, e.BarcodeData, 0, nTempLength);
                String str = enc.GetString(barcodeBuffer, 0, barcodeBuffer.Length);
                return str;
            }
            return null;
        }

        public static string[] decodePDF417RegCivil(string str)
        {
            /*Hashtable
            Dictionary<string,string> data=new Dictionary<string, string>(2); 
            
            data.Add("rut",str.Substring(0,9));
            data.Add("apellidoPat",str.Substring(19,30));

            return data;*/
            return new string[]
            {
                str.Substring(0, 9).Trim(), //rut
                str.Substring(19, 30).Trim() //apellido
            }
            ;
        }
    }
}
